package wiki.hitime.stl.daq.manager;

import wiki.hitime.stl.daq.bean.db.DaqExecuteRecord;
import wiki.hitime.stl.daq.bean.db.DaqExecuteRule;
import wiki.hitime.stl.daq.bean.dto.manage.ExecuteRecordDTO;
import wiki.hitime.stl.daq.bean.dto.req.ExecuteTaskRecordListReqDTO;
import wiki.hitime.stl.daq.enums.ProcessStatusEnum;
import wiki.hitime.stl.daq.mapper.DaqExecuteRecordMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangdaoping
 * @create 2019-07-15 18:23
 */
@Service
public class DaqExecuteRecordManager {

    @Resource
    private DaqExecuteRecordMapper daqExecuteRecordMapper;

    /**
     * 添加未处理记录
     *
     * @param executeRule 执行规则
     * @return 记录id
     */
    public long addNotProcessRecord(DaqExecuteRule executeRule) {
        DaqExecuteRecord executeRecord = DaqExecuteRecord.builder()
                .executeRuleId(executeRule.getId())
                .ruleName(executeRule.getRuleName())
                .cronExpression(executeRule.getCronExpression())
                .startTime(DateTime.now().toDate())
                .processStatus(ProcessStatusEnum.WAITING.getStatus())
                .ctlVersion(executeRule.getCtlVersion())
                .build();
        daqExecuteRecordMapper.insertSelective(executeRecord);
        return executeRecord.getId();
    }

    /**
     * 更新记录为处理成功
     *
     * @param recordId 记录编号
     */
    public void updateProcessSucceed(Long recordId) {
        DaqExecuteRecord executeRecord = DaqExecuteRecord.builder()
                .id(recordId)
                .endTime(DateTime.now().toDate())
                .processStatus(ProcessStatusEnum.SUCCEED.getStatus())
                .build();
        daqExecuteRecordMapper.updateByPrimaryKeySelective(executeRecord);
    }

    /**
     * 更新记录为处理失败
     *
     * @param recordId 记录编号
     */
    public void updateProcessFailed(Long recordId, String processMsg) {
        processMsg = processMsg.length() > 2000 ? processMsg.substring(0, 2000) : processMsg;
        DaqExecuteRecord executeRecord = DaqExecuteRecord.builder()
                .id(recordId)
                .processStatus(ProcessStatusEnum.FAILED.getStatus())
                .processMsg(processMsg)
                .build();
        daqExecuteRecordMapper.updateByPrimaryKeySelective(executeRecord);
    }

    /**
     * 获取规则对应最大的记录
     *
     * @param executeRuleIdList
     * @return
     */
    public List<DaqExecuteRecord> listMax(List<Long> executeRuleIdList) {
        return daqExecuteRecordMapper.listMax(executeRuleIdList);
    }

    /**
     * 分页获取执行记录
     *
     * @param reqDTO
     * @return
     */
    public PageInfo listByPage(ExecuteTaskRecordListReqDTO reqDTO) {
        Example selectExample = new Example(DaqExecuteRecord.class, true, true);
        selectExample.createCriteria().andEqualTo("executeRuleId", reqDTO.getExecuteRuleId()).andEqualTo("isDelete", Boolean.FALSE);
        selectExample.setOrderByClause("id DESC");
        PageHelper.startPage(reqDTO.getPageInfo());
        List<DaqExecuteRecord> pageResult = daqExecuteRecordMapper.selectByExample(selectExample);
        Page page = (Page) pageResult;
        List<DaqExecuteRecord> daqExecuteRecordList = ((Page<DaqExecuteRecord>) pageResult).getResult();
        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(daqExecuteRecordList.stream().map(this::convertRecordDTO).collect(Collectors.toList()));
        return pageInfo;
    }

    private ExecuteRecordDTO convertRecordDTO(DaqExecuteRecord daqExecuteRecord) {
        ProcessStatusEnum executeProcessStatusEnum = ProcessStatusEnum.valueOf(daqExecuteRecord.getProcessStatus());
        Assert.notNull(executeProcessStatusEnum, "处理状态枚举为空");
        ExecuteRecordDTO executeRecordDTO = ExecuteRecordDTO.builder()
                .executeRecordId(daqExecuteRecord.getId())
                .startTime(daqExecuteRecord.getStartTime())
                .endTime(daqExecuteRecord.getEndTime())
                .executeProcessStatus(daqExecuteRecord.getProcessStatus())
                .executeProcessName(executeProcessStatusEnum.getMsg())
                .executeProcessMsg(daqExecuteRecord.getProcessMsg())
                .build();
        return executeRecordDTO;
    }


}
